var Q = require('q'),
	operationController = require('../../../CBO/server/controllers/Operation.server.controller'),
    barcodeMasterController = require('../../../Barcode/server/controllers/BarcodeMaster.server.controller'),
    bizRecordController = require('../../../Barcode/server/controllers/BizRecord.server.controller'),
    qcRecordController = require('../../../QC/server/controllers/QCRecord.server.controller'),
    workController = require('../../../CBO/server/controllers/Work.server.controller'),
    completePlanController = require('../../../ProduceWork/server/controllers/CompletePlan.server.controllers'),
    Transaction = require('../../../Base/server/controllers/Transaction'),
    BaseFun = require('../../../Base/server/controllers/Function'),
    BaseEnum = require('../../../Base/server/controllers/Enum'),
    QCEnum = require('../../../QC/server/controllers/Enum.server.controller'),
    PWEnum = require('../../../ProduceWork/server/controllers/Enum.server.controller'),
    BarcodeEnum = require('../../../Barcode/server/controllers/Enum.server.controller'),
    enumController = require('../../../QC/server/controllers/Enum.server.controller');
//1,根据传入的barcode(eg:test12345)在条码主档表中找到条码主档ID
//2,在装配关系表中通过上步找到的条码主档ID==装配条码ID（AssemblyBarcode）
//，找到对应的条码主档ID（BarcodeMaster）
//3,获取芯片ID、出货批次、尺寸（扩展字段1）、物料号（关联物料档案获取）。


exports.getAssemblyBarcodeData = function(req, res) {
	var assemblyBarcode = req.body.Parameter.Barcode;

	barcodeMasterController.findBarcodeMasterByBarcode(assemblyBarcode, function(err, barcodeMaster){
        if (err) {
            res.json({
                Data: null,
                Error: err
            });
            return;
        }
        if (barcodeMaster == null) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '查询镭射标失败';
            newErr.message = '未找到对应的镭射标！';
            res.json({
                Data: null,
                Error: newErr
            });
            return;
        }
        barcodeMasterController.findAssemblyBarcodeMaster(barcodeMaster._id, function(err, assemblyBarcodeMaster) {
			if (err) {
				res.json({
	                Data: null,
	                Error: err
	            });
			} else {
				if (!assemblyBarcodeMaster || !assemblyBarcodeMaster.BarcodeMaster) {
					var newErr = new Error();
					newErr.leval = 9;
					newErr.title = '查询芯片失败';
					newErr.message = '未找到对应的芯片！';
					deferred.resolve({
						Data: null,
						Error: newErr
					});
					return;
				}
				var barcodeMaster = assemblyBarcodeMaster.BarcodeMaster;
				if (barcodeMaster.QCStatus !== QCEnum.QCStatus.Qualified.Value) {
					var newErr = new Error();
					newErr.leval = 9;
					newErr.title = '非法条码';
					newErr.message = '不是合格单品';
					res.json({
					    Data: null,
					    Error: newErr
					});
					return;
				}
				if (barcodeMaster.Status === BarcodeEnum.BarcodeStatus.Complete.Value) {
					var newErr = new Error();
					newErr.leval = 9;
					newErr.title = '非法条码';
					newErr.message = '该单品已完工';
					res.json({
					    Data: null,
					    Error: newErr
					});
					return;
				}
				res.json({
					Data: barcodeMaster,
					Error: null
				});
			}
		});
    });
};

//获取工位和作业信息
exports.getLocationAndWork = function(req, res) {
	var deviceId = req.body.Parameter.DeviceId;

	findLocationAndWork(deviceId).then(function(result) {
		res.json(result);
	}, function(err) {
		res.json(err);
	});
};

//包装入库
exports.doStocking = function (req, res) {
    var parameter = req.body.Parameter,
	    wareHouseId = parameter.wareHouseId,
	    packagecode = parameter.Packagecode,//包装货号
		barcodeMasters = parameter.barcodeMasters,//条码主档合集
		ItemMaster = parameter.ItemMaster,
        Terminal = parameter.Terminal,
        TerminalName = parameter.TerminalName,
        Work = parameter.Work,
        WorkName = parameter.WorkName,
        WorkLocation = parameter.WorkLocation,
        WorkLocationName = parameter.WorkLocationName,
        userId = parameter.UserID;
    var transactions = [];//保存事务的
    var operRecord;//保存工序记录
    var completePlanIds;
    var packageBarcodeData = {
    	Barcode: packagecode,
        BarcodeType: 6,
        _id: BaseFun.getObjectId(),
        RowStatus: BaseEnum.RowStatus.Insert.Value,
        CreatedBy: userId
    };
    transactions.push({
        EntityName: 'BarcodeMaster',
        Records: [packageBarcodeData]
    });  
    //根据物料和作业查找工序
    queryOperation(ItemMaster, Work).then(function(operationRecord) {
        operRecord = operationRecord;
        var bindContext = {
            Work: Work,
            WorkName: WorkName,
            User: userId,
            WorkLocation: WorkLocation,
            WorkLocationName: WorkLocationName
        }
        //流水校验
        return doStockingStreamValidation(barcodeMasters,operationRecord,bindContext);
    }).then(function(trans) {
        if(trans){
            transactions = transactions.concat(trans);
        }
    	//增加多个流水主档
        var bizRecords = [];
        var bizRecordSys = [];//带SysVersion
    	var dateNow = Date.now();
    	for (var i = 0; i < barcodeMasters.length; i++) {
    		var barcodeMaster = barcodeMasters[i];
    		if(barcodeMaster.QCStatus!=4){//不是返工的入库

                var bizRecord = {
                    _id: BaseFun.getObjectId(),
                    RowStatus: BaseEnum.RowStatus.Insert.Value,
                    CreatedBy: userId,
                    CollectDateTime: dateNow,
                    Users: [userId],
                    // BusinessStatus: 1,//业务状态：完成
                    QCType: barcodeMaster.QCType,//质检类型：全检
                    QCUser: userId,
                    QCDateTime: dateNow,
                    QCStatus: barcodeMaster.QCStatus,
                    BarcodeMaster:barcodeMaster._id,
                    Work:Work,
                    WorkName:WorkName,
                    WorkLocation:WorkLocation,
                    WorkLocationName:WorkLocationName,
                    Terminal:Terminal,
                    TerminalName:TerminalName,
                    Operation:operRecord._id,
                    OperationName:operRecord.Name
                };
    			bizRecords.push(bizRecord);
                bizRecord.SysVersion = barcodeMaster.SysVersion;
                bizRecordSys.push(bizRecord);
    		}
    	};
        transactions.push({
	        EntityName: 'BizRecord',
	        Records: bizRecords
	    });
	    //更新多个条码主档  
        var updateRecords = [];
	    for (var i = 0; i < bizRecordSys.length; i++) {
	    	var bizRecordSy = bizRecordSys[i];
	        updateRecords.push({
                SysVersion: bizRecordSy.SysVersion,
	          	RowStatus: BaseEnum.RowStatus.Modify.Value,
                CreatedBy: userId,
	          	_id: bizRecordSy.BarcodeMaster,
	            Users: [userId],  
	            BizRecord: bizRecordSy._id,
	            Work: bizRecordSy.Work,
	            WorkName: bizRecordSy.WorkName,
	            WorkLocation: bizRecordSy.WorkLocation,
	            WorkLocationName: bizRecordSy.WorkLocationName,
	            Terminal: bizRecordSy.Terminal,
	            TerminalName: bizRecordSy.TerminalName,
	            Operation: bizRecordSy.Operation,
	            OperationName: bizRecordSy.OperationName
	        });    
	    };
	    transactions.push({
	        EntityName: 'BarcodeMaster',
	        Records: updateRecords
	    });
	    //增加多个装配关系记录
	    var addAssemblyRecords = [];
	    barcodeMasters.forEach(function (barcodeMaster) {
	    	addAssemblyRecords.push({
                BarcodeMaster: packageBarcodeData._id,
		        AssemblyBarcode: barcodeMaster._id,
		        AssemblyType: 1,
		        CollectDateTime: dateNow,
				RowStatus: BaseEnum.RowStatus.Insert.Value,
		        CreatedBy: userId,
		        _id: BaseFun.getObjectId()
	    	})  
	    });
	    transactions.push({
	        EntityName: 'AssemblyRelation',
	        Records: addAssemblyRecords
	    });
        return doAllStocking(barcodeMasters, wareHouseId, userId);
    }).then(function(resultData) {
    	completePlanIds = resultData.completePlanIds;
        if(resultData){
            transactions.push({
                EntityName: 'RcvRecord',
                Records: resultData.addStockRecords
            });  
        }
        return queryAndUpdateCompletePlan(completePlanIds,userId);
    }).then(function(updateData) {
        if(updateData){
            transactions.push({
                EntityName: 'CompletePlan',
                Records: updateData.updateCPDatas
            }); 
            transactions.push({
                EntityName: 'CompletePlan',
                Records: updateData.updateStateCPDatas
            }); 
        }
        return Q.nfcall(Transaction.BatchSaveByTran, transactions);
    }).then(function() {
        res.json({
            Data: true,
            Error: null
        });
    }).catch(function(err) {
        res.json({
            Data: null,
            Error: err
        });
    })
    .done();
};


//存多条码主档入库记录和存完工计划id
function doAllStocking(barcodeMasters,wareHouseId,userId) {
    var deferred = Q.defer();
    var promises = [];
    var addStockRecords = [];
    //存入多个完工计划id
    var completePlanIds = [];
    barcodeMasters.forEach(function (barcodeMaster) {
        promises.push(queryBarcodeMaster(barcodeMaster.Barcode).then(function(result) {
	        var dateNow = Date.now();
            addStockRecords.push({
           	    BarcodeMaster: result._id,
	            Barcode: result.Barcode,
	            RcvBusinessType: 0,
	            BusinessDocID: result.MO,
	            ItemMaster: result.ItemMaster,
	            RcvUser: userId,
	            RcvDateTime: dateNow,
	            RcvQty: 1,
	            RcvOperation: result.Operation,
	            BizRecord: result.BizRecord,
	            WareHouse: wareHouseId,
                RowStatus: BaseEnum.RowStatus.Insert.Value,
                CreatedBy: userId,
                _id: BaseFun.getObjectId()
            });
           
            completePlanIds.push(result.CompletePlan);

        }, function(err) {
          
        }));   
    });
	Q.all(promises).then(function () {
        deferred.resolve({
        	addStockRecords: addStockRecords,
        	completePlanIds: completePlanIds
        });
	});									        	

    return deferred.promise;
} 

//校验流水
function doStockingStreamValidation(barcodeMasters,operationRecord,bindContext) {
    var deferred = Q.defer();

 	var barcodepromises = [];
    var trans = [];
    barcodeMasters.forEach(function (barcodeMaster) {
        barcodepromises.push(checkBizRecord(barcodeMaster.Barcode,operationRecord,bindContext,trans));     
    });
    Q.all(barcodepromises).then(function () {
        deferred.resolve(trans);
    });

    return deferred.promise;
} 

function checkBizRecord(barcode,operationRecord,bindContext,trans){
	var deferred = Q.defer();
 
	findBarcodeMaster(barcode).then(function (record) {	                    
	    barcodeMasterController.streamValidation(record, operationRecord, bindContext).then(function (processException){
            if (processException) {
                trans.push(processException);
            }
	        deferred.resolve();
	    },function(error){
	        deferred.reject(err);
	    }); 
	},function(error){
	    deferred.reject(err);
	});
    
    return deferred.promise;
}

function findBarcodeMaster(barcode) {
    var deferred = Q.defer();

    barcodeMasterController.findBarcodeMaster(barcode, function (err, barcodeMaster) {
        if (err) {
            deferred.reject(err);
            return;
        }
        if (barcodeMaster == null) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '无法识别条码';
            newErr.message = '无法识别的条码，请重新扫描！';
            deferred.reject(newErr);
            return;
        }
        deferred.resolve(barcodeMaster);
    });

    return deferred.promise;
}

function queryBarcodeMaster (Barcode) {
    var deferred = Q.defer();
    barcodeMasterController.findBarcodeMasterByBarcode(Barcode, function (err, result) {
        if (err) {
            deferred.reject(err);
            return;
        }
        else{
        	if (result) {
               deferred.resolve(result); 
            } 
        }            
    });  
    return deferred.promise;
}
//循环完工计划id数组查找并更新数据
function queryAndUpdateCompletePlan(completePlanIds,userId) {
	var deferred = Q.defer();
	var completePlanPromises = [];
	var updateCPDatas = [];
	var updateStateCPDatas = [];
	completePlanIds.forEach(function (completePlanId) {
        completePlanPromises.push(queryCompletePlan(completePlanId,updateCPDatas,updateStateCPDatas,userId));   
    });
    Q.all(completePlanPromises).then(function () {         
		deferred.resolve({
			updateCPDatas:updateCPDatas,
			updateStateCPDatas:updateStateCPDatas
		});
    }, function (err) {
    	deferred.reject(err);
    });

}

//查找完工计划表中完工量
function queryCompletePlan (completePlanId,updateCPDatas,updateStateCPDatas,userId) {
    var deferred = Q.defer();
    completePlanController.findCompletePlan(completePlanId, function (err, result) {
        if (err) {
            deferred.reject(err);
        } else {
        	if(result){
                updateCPDatas.push({
                    SysVersion: result.SysVersion,
                    RowStatus: BaseEnum.RowStatus.Modify.Value,
                    CreatedBy: userId,
	          	    _id: completePlanId,
	          	    CompleteQty:result.CompleteQty?result.CompleteQty+1:1
                });
                deferred.resolve();

                if (result.CompleteQty+1 === result.Qty) {
                    updateStateCPDatas.push({
                        SysVersion: result.SysVersion,
                        RowStatus: BaseEnum.RowStatus.Modify.Value,
	                    CreatedBy: userId,
		          	    _id: completePlanId,
		          	    Status:PWEnum.CompletePlanStatus.Cancel.Value//2 终止
                    });
                    deferred.resolve();
	        	} else {
	        		deferred.resolve();
	        	}

        	}else{
        		var newErr = new Error();
	            newErr.leval = 9;
	            newErr.title = '查询完工计划数据失败';
	            newErr.message = '没有找到对应的完工计划数据';
	            deferred.reject(newErr);
        	}
        }
    });
    return deferred.promise;
}

// //查找完工计划表中完工量
// function queryCompletePlan (completePlanId) {
//     var deferred = Q.defer();
//     completePlanController.findCompletePlan(completePlanId, function (err, result) {
//         if (err) {
//             deferred.reject(err);
//         } else {
//         	if (result) {
//         	   completePlanController.updateByValue(completePlanId,{CompleteQty:result.CompleteQty?result.CompleteQty+1:1}, function (errData, resultData) {
// 			        if (errData) {
// 			            deferred.reject(errData);
// 			        } else {
// 			        	if (resultData.ok===1&&result.CompleteQty+1 === result.Qty) {
// 			        	   	  completePlanController.updateByValue(completePlanId,{Status:2}, function (errStatus, resultStatus) {	   	  	    
// 							        if (errStatus) {
// 							            deferred.reject(errStatus);
// 							        } else {
// 							        	if (resultStatus) {
// 							        	   deferred.resolve(resultStatus); 
// 							            } 
// 							        }            
// 							  }); 
// 			        	} else {
// 			        		deferred.resolve(resultData); 
// 			        	}
// 			        } 		                  
// 			    });                 
//             } else {
//             	deferred.resolve(); 
//             }
//         }            
//     });  
//     return deferred.promise;
// }

//根据物料和作业查找工序
function queryOperation(itemMaster, work) {
    var deferred = Q.defer();

    if (!itemMaster) {
        var newErr = new Error();
        newErr.leval = 9;
        newErr.message = '主档未绑定物料';
        deferred.reject(newErr);
        return;
    }
    operationController.findByItemMasterAndWork(itemMaster, work, function(err, result) {
        if (err) {
            deferred.reject(err);
            return;
        }
        if (!result) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '非法数据';
            newErr.message = '没有找到对应的工序';
            deferred.reject(newErr);
            return;
        }
        deferred.resolve(result);
    });

    return deferred.promise;
}


//获取装配条码的信息
function doAssemblyBarcodeData(barcode) {
	var deferred = Q.defer();
	barcodeMasterController.findAssemblyBarcodeMasterId(barcode, function(err, barcodeMaster) {
		if (err) {
			deferred.reject(err);
			return;
		} else {
			if (barcodeMaster._id) {
				barcodeMasterController.findAssemblyBarcodeMaster(barcodeMaster._id, function(err, barcodeMaster) {
					if (err) {
						deferred.reject(err);
						return;
					}
					if (barcodeMaster == null) {
						var newErr = new Error();
						newErr.leval = 9;
						newErr.title = '条码扫描失败';
						newErr.message = '该条码没有对应的条码主档！';
						deferred.resolve({
							Data: null,
							Error: newErr
						});
					} else {
						var result = {
							_id: barcodeMaster.BarcodeMaster._id,
							Barcode: barcodeMaster.BarcodeMaster.Barcode,
							ItemMasterCode: barcodeMaster.BarcodeMaster.ItemMasterCode,
							ShipLotNumber: barcodeMaster.BarcodeMaster.ShipLotNumber
						};
						deferred.resolve({
							Data: result,
							Error: null
						});
					}
					// deferred.resolve(barcodeMaster);
				});
			}
		}
	});
	return deferred.promise;
};
